1 using System;
2 using
System.Collections.Generic;
3 using
UnityEngine;
4 using
UnityEngine.Assertions;
5 using
Random = UnityEngine.Random;
6
7 namespace
ProceduralToolkit.Examples
8 {

9     ///
<summary>
10     ///
A simple Perlin noise based low poly terrain generator
11     ///
</summary>
12     
public static class LowPolyTerrainGenerator
13     {
14         
[Serializable]
15         
public class Config
16         {
17             
public Vector3 terrainSize = new Vector3(20, 1, 20);
18             
public float cellSize = 1;
19             
public float noiseScale = 5;
20             
public Gradient gradient;
21         }
22
23         
public static MeshDraft TerrainDraft(Config config)
24         {
25             Assert.IsTrue(config.terrainSize.x >
0);
26             Assert.IsTrue(config.terrainSize.z >
0);
27             Assert.IsTrue(config.cellSize >
0);
28
29             
var noiseOffset = new Vector2(Random.Range(0f, 100f), Random.Range(0f, 100f));
30
31             
int xSegments = Mathf.FloorToInt(config.terrainSize.x/config.cellSize);
32             
int zSegments = Mathf.FloorToInt(config.terrainSize.z/config.cellSize);
33
34             
float xStep = config.terrainSize.x/xSegments;
35             
float zStep = config.terrainSize.z/zSegments;
36             
int vertexCount = 6*xSegments*zSegments;
37             
var draft = new MeshDraft
38             {
39                 name =
"Terrain",
40                 vertices =
new List<Vector3>(vertexCount),
41                 triangles =
new List<int>(vertexCount),
42                 normals =
new List<Vector3>(vertexCount),
43                 colors =
new List<Color>(vertexCount)
44             };
45
46             
for (int i = 0; i < vertexCount; i++)
47             {
48                 draft.vertices.Add(Vector3.zero);
49                 draft.triangles.Add(
0);
50                 draft.normals.Add(Vector3.zero);
51                 draft.colors.Add(Color.black);
52             }
53
54             
for (int x = 0; x < xSegments; x++)
55             {
56                 
for (int z = 0; z < zSegments; z++)
57                 {
58                     
int index0 = 6*(x + z*xSegments);
59                     
int index1 = index0 + 1;
60                     
int index2 = index0 + 2;
61                     
int index3 = index0 + 3;
62                     
int index4 = index0 + 4;
63                     
int index5 = index0 + 5;
64
65                     
float height00 = GetHeight(x + 0, z + 0, xSegments, zSegments, noiseOffset, config.noiseScale);
66                     
float height01 = GetHeight(x + 0, z + 1, xSegments, zSegments, noiseOffset, config.noiseScale);
67                     
float height10 = GetHeight(x + 1, z + 0, xSegments, zSegments, noiseOffset, config.noiseScale);
68                     
float height11 = GetHeight(x + 1, z + 1, xSegments, zSegments, noiseOffset, config.noiseScale);
69
70                     
var vertex00 = new Vector3((x + 0)*xStep, height00*config.terrainSize.y, (z + 0)*zStep);
71                     
var vertex01 = new Vector3((x + 0)*xStep, height01*config.terrainSize.y, (z + 1)*zStep);
72                     
var vertex10 = new Vector3((x + 1)*xStep, height10*config.terrainSize.y, (z + 0)*zStep);
73                     
var vertex11 = new Vector3((x + 1)*xStep, height11*config.terrainSize.y, (z + 1)*zStep);
74
75                     draft.vertices[index0] = vertex00;
76                     draft.vertices[index1] = vertex01;
77                     draft.vertices[index2] = vertex11;
78                     draft.vertices[index3] = vertex00;
79                     draft.vertices[index4] = vertex11;
80                     draft.vertices[index5] = vertex10;
81
82                     draft.colors[index0] = config.gradient.Evaluate(height00);
83                     draft.colors[index1] = config.gradient.Evaluate(height01);
84                     draft.colors[index2] = config.gradient.Evaluate(height11);
85                     draft.colors[index3] = config.gradient.Evaluate(height00);
86                     draft.colors[index4] = config.gradient.Evaluate(height11);
87                     draft.colors[index5] = config.gradient.Evaluate(height10);
88
89                     Vector3 normal000111 = Vector3.Cross(vertex01 - vertex00, vertex11 - vertex00).normalized;
90                     Vector3 normal001011 = Vector3.Cross(vertex11 - vertex00, vertex10 - vertex00).normalized;
91
92                     draft.normals[index0] = normal000111;
93                     draft.normals[index1] = normal000111;
94                     draft.normals[index2] = normal000111;
95                     draft.normals[index3] = normal001011;
96                     draft.normals[index4] = normal001011;
97                     draft.normals[index5] = normal001011;
98
99                     draft.triangles[index0] = index0;
100                     draft.triangles[index1] = index1;
101                     draft.triangles[index2] = index2;
102                     draft.triangles[index3] = index3;
103                     draft.triangles[index4] = index4;
104                     draft.triangles[index5] = index5;
105                 }
106             }
107
108             
return draft;
109         }
110
111         
private static float GetHeight(int x, int z, int xSegments, int zSegments, Vector2 noiseOffset, float noiseScale)
112         {
113             
float noiseX = noiseScale*x/xSegments + noiseOffset.x;
114             
float noiseZ = noiseScale*z/zSegments + noiseOffset.y;
115             
return Mathf.PerlinNoise(noiseX, noiseZ);
116         }
117     }
118 }


Gõ tìm kiếm nhanh...